home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / tcoop.arc / TCOOP2.ARC / BROWSE1.C next >
Encoding:
C/C++ Source or Header  |  1991-10-26  |  8.7 KB  |  310 lines

  1. /* browse.c
  2.  * This program allows you to view the contents of an ASCII
  3.  * file. Once a file is displayed, you can scroll through the
  4.  * file using the cursor pad keys (PgUp, PgDn, and so on). To
  5.  * use the program, issue the following command at the DOS
  6.  * prompt:
  7.  *                      browse <filename>
  8.  *
  9.  * NOTE: COMPILE THIS IN LARGE MODEL ONLY
  10.  */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <alloc.h>
  15. #include <dos.h>
  16. #include <dir.h>
  17. #include <conio.h>
  18. #include <sys\stat.h>
  19. #include <io.h>
  20.  
  21. #define MaxBufSize 65520L /* Roughly 64K maximum file size */
  22. #define ScrSize    23     /* Number of text lines per screen */
  23. #define TabSize    5      /* Five spaces per tab */
  24. #define EscKey     27     /* Extended key codes */
  25. #define PgUp       73
  26. #define PgDn       81
  27. #define Home       71
  28. #define EndKey     79
  29. #define UpKey      72
  30. #define DnKey      80
  31. #define Alt_S      31     /* The search key */
  32. #define Screen     (*ScreenPtr)
  33. #define TabKey     9
  34. #define CR         10     /* Carriage return */
  35.  
  36. struct Texel {            /* Record used for direct */
  37.   char Ch;                /* screen access */
  38.   unsigned char Attr;     /* Character attribute */
  39. };
  40.  
  41. typedef struct Texel ScreenArea[25][80];
  42.  
  43. FILE *InFile;
  44. ScreenArea far *ScreenPtr;
  45. long Time, Size;
  46. char *BufPtr, Ch;
  47. int LinePtr[2000]; /* Indexes of beginning lines in BufPtr */
  48. int Attr, NoBytes, I, Lc, Bot, End;
  49.  
  50. char *GetStr(char *Str);
  51. /* CODE CHANGE: Must return a far pointer! */
  52. ScreenArea far *SelectMonitor(void);
  53. void DisplayFStat(char *fname, FILE *InFile, struct ffblk *ffblk);
  54. void DisplayCommands(void);
  55. void ShowScreen(void);
  56. void FileSearch(void);
  57. void ProcessInput(char Ch);
  58.  
  59. int main(int argc, char *argv[])
  60. {
  61.   struct ffblk ffblk;
  62.   int DosError;
  63.  
  64.   clrscr();
  65.   if (argc != 2) {
  66.     printf("Incorrect number of arguments\n");
  67.     printf("To browse a file use the command:\n");
  68.     printf("\tbrowse <filename>\n");
  69.     exit(1);
  70.   }
  71.   ScreenPtr = SelectMonitor();
  72.   DosError = findfirst(argv[1], &ffblk, 0);
  73.   if (DosError != 0) {
  74.     printf("Can't find the file %s\n", argv[1]);
  75.     exit(1);
  76.   }
  77.   if ((InFile=fopen(argv[1],"r")) == NULL) {   /* Open file */
  78.     printf("Cannot open file: %s\n", argv[1]);
  79.     exit(1);
  80.   }
  81.   /* Allocate memory for the file buffer */
  82.   if (ffblk.ff_fsize >= MaxBufSize) {
  83.     printf("File too large: %s\n", argv[1]);
  84.     exit(1);
  85.   }
  86.   if ((BufPtr=malloc(ffblk.ff_fsize)) == NULL) {
  87.     printf("Not enough memory\n");
  88.     exit(1);
  89.   }
  90.  
  91.   DisplayFStat(argv[1], InFile, &ffblk);
  92.   DisplayCommands();
  93.   NoBytes = read(fileno(InFile), BufPtr, ffblk.ff_fsize);
  94.   Lc = 0;
  95.   LinePtr[Lc++] = 0;      /* Initialize the line index array */
  96.   for (I=0; I<NoBytes; I++)
  97.     if (BufPtr[I] == CR)
  98.       LinePtr[Lc++] = I + 1;
  99.  
  100.   fclose(InFile);
  101.   if (Lc > ScrSize)       /* Set the index that can display */
  102.     Bot = Lc - ScrSize;   /* the last screen full of the file */
  103.   else Bot = 0;
  104.   End = Lc - 1;           /* Save line index to end of file */
  105.   Lc = 0;                 /* Set the top line index */
  106.   ShowScreen();
  107.   do {
  108.     Ch = getch();
  109.     switch (Ch) {
  110.       case 0:             /* Extended key pressed */
  111.         Ch = getch();
  112.         ProcessInput(Ch); /* Perform operation */
  113.         break;
  114.       case EscKey: break; /* Do nothing for now */
  115.       default: putch(7);  /* Illegal key; sound the bell */
  116.     }
  117.   } while (Ch != EscKey);
  118.   free(BufPtr);
  119.   textbackground(0);      /* Restore the screen */
  120.   textcolor(7);
  121.   clrscr();
  122.   return 0;
  123. }
  124.  
  125. char *GetStr(char *Str)
  126. /* Read a string at the current cursor location. Press Esc
  127.    to abort read operation. */
  128. {
  129.   char Ch;
  130.   int Count = 0;
  131.  
  132.   while ((Ch=getch()) != 13 && Ch != EscKey) {
  133.     printf("%c", Ch);
  134.     Str[Count++] = Ch;
  135.   }
  136.   if (Ch == EscKey) return NULL;
  137.   Str[Count] = '\0';            /* Terminate string */
  138.   return Str;
  139. }
  140.  
  141. /* CODE CHANGE: Must return a far pointer! */
  142. ScreenArea far *SelectMonitor(void)
  143. /* Determine the type of graphics card installed and return
  144.    the memory address of the video memory */
  145. {
  146.   union REGS Regs;
  147.   unsigned Segment, Offset;
  148.  
  149.   Regs.h.ah = 15;
  150.   int86(0x10, &Regs, &Regs);
  151.   if (Regs.h.al == 7)
  152.     Segment = 0xB000;       /* Monochrome */
  153.   else Segment = 0xB800;    /* Graphics */
  154.   Offset = Regs.h.bh * (unsigned)0x1000;  /* Calculate video page */
  155.   return (ScreenArea *)(((long)Segment << 16) | (long)Offset);
  156. }
  157.  
  158. void DisplayFStat(char *fname, FILE *InFile, struct ffblk *ffblk)
  159. /* Display the first status line of file information  */
  160. /* including file name, size, date, and time          */
  161. /* CODE CHANGE: move for loop to last part of routine */
  162. {
  163.   int Col;
  164.   struct ftime ft;
  165.   char AtStr[8];
  166.  
  167.   textbackground(7);           /* Text is set to black on white */
  168.   textcolor(0);
  169.  
  170.   gotoxy(3,1);                 /* Display filename */
  171.   printf("File: %s",fname);
  172.   gotoxy(26,1);
  173.   getftime(fileno(InFile),&ft);
  174.   printf("Date: %02u-%02u-%04u",ft.ft_month,
  175.          ft.ft_day,ft.ft_year+1980);
  176.   gotoxy(48,1);                /* Display size */
  177.   printf("Size: %ld",ffblk->ff_fsize);
  178.  
  179.   if (ffblk->ff_attrib == FA_RDONLY) /* Determine attributes */
  180.     strcpy(AtStr,"R");
  181.   else
  182.     strcpy(AtStr,"R-W");
  183.   if (ffblk->ff_attrib == FA_HIDDEN) strcat(AtStr,"-H");
  184.   if (ffblk->ff_attrib == FA_SYSTEM) strcat(AtStr,"-S");
  185.   gotoxy(63,1);
  186.   printf("Attr: %s",AtStr);      /* Display attributes */
  187.   for (Col=0; Col<80; Col++)   /* Put status bar in reverse video */
  188.      Screen[0][Col].Attr = 112;
  189. }
  190.  
  191. void DisplayCommands(void)
  192. /* Displays the command bar at the last line of the screen */
  193. /* CODE CHANGE: Change the printf() statement around with  */
  194. /* the for loop                                            */
  195. {
  196.   int Col;
  197.  
  198.   gotoxy(2,25);
  199.   printf("<Home=Top>  <End=Bot>  <PgUp=Prev>  <PgDn=Next> "
  200.          "<Alt-S=Search>  <Esc=Quit>");
  201.   for (Col=0; Col<80; Col++) Screen[24][Col].Attr = 112;
  202. }
  203.  
  204. void ShowScreen(void)
  205. /* Display a screen image containing 23 lines of the file */
  206. {
  207.   int Row, Col, TLc, I, Tp;
  208.  
  209.   TLc = Lc;       /* Start with the current line index */
  210.   for (Row=0; Row<ScrSize && Row<=End; Row++) {
  211.     Tp = LinePtr[TLc];
  212.     for (Col=0; Col<80 && Tp<NoBytes &&
  213.                 BufPtr[Tp] != CR; Tp++) {
  214.       if (BufPtr[Tp] == TabKey)     /* Look for tab key */
  215.         for (I=0; I<TabSize && Col<80; I++)
  216.           /* Replace tab with spaces */
  217.           Screen[Row+1][Col++].Ch = ' ';
  218.       else Screen[Row+1][Col++].Ch = BufPtr[Tp];
  219.     }
  220.     for (; Col<80; Col++) Screen[Row+1][Col].Ch = ' ';
  221.     TLc++;
  222.   }
  223.   // Fill out the screen if the file has fewer than one
  224.   // screen full of lines
  225.   for (; Row<ScrSize; Row++)
  226.     for (Col=0; Col<80; Col++)
  227.       Screen[Row+1][Col].Ch = ' ';
  228. }
  229.  
  230. void FileSearch(void)
  231. /* Search the file for a string starting from the current
  232.    top line displayed. If a match is found, the line
  233.    containing the string is highlighted. */
  234. {
  235.   int Col, I, P;
  236.   char *Ptr, SearchStr[81], *S, Line[81];
  237.  
  238.   for (Col=1; Col<=78; Col++) Screen[24][Col].Ch = ' ';
  239.   gotoxy(2,25); printf("Search for: ");
  240.   /* Get the search string */
  241.   if ((S=GetStr(SearchStr)) == NULL) {
  242.     DisplayCommands();   /* No string entered */
  243.     return;
  244.   }
  245.   I = Lc;
  246.   do {
  247.     P = LinePtr[I];
  248.     for (Col=0; Col<80 && BufPtr[P+Col] != CR; Col++)
  249.       Line[Col] = BufPtr[P+Col];
  250.     Line[Col] = '\0';        /* Terminate line string */
  251.     Ptr = strstr(Line,S);    /* Look for a match */
  252.     I++;
  253.   } while (Ptr == NULL && I <= End);
  254.  
  255.   if (Ptr != NULL) {
  256.     if (I > Lc+ScrSize) {
  257.       Lc = I - ScrSize;
  258.       ShowScreen();
  259.     }
  260.     /* Highlight line with match */
  261.     for (Col=0; Col<80; Col++) Screen[I-Lc][Col].Attr = 112;
  262.     /* Wait until a key is pressed */
  263.     if (getch() == 0) (void)getch();
  264.     /* Set line of text back to normal */
  265.     for (Col=0; Col<80; Col++) Screen[I-Lc][Col].Attr = 7;
  266.   }
  267.   DisplayCommands();
  268. }
  269.  
  270. void ProcessInput(char Ch)
  271. /* Process the input keys */
  272. {
  273.   switch (Ch) {
  274.     case PgUp:
  275.       if (Lc-ScrSize > 0) Lc -= ScrSize;
  276.         else Lc = 0;
  277.       ShowScreen();
  278.       break;
  279.     case PgDn:
  280.       if (Lc+ScrSize < Bot && Bot >= ScrSize) Lc += ScrSize;
  281.         else Lc = Bot;
  282.       ShowScreen();
  283.       break;
  284.     case UpKey:
  285.       if (Lc > 0) {
  286.         Lc--;
  287.         ShowScreen();
  288.       }
  289.       break;
  290.     case DnKey:
  291.       if (Lc < Bot && Bot >= ScrSize) {
  292.         Lc++;
  293.         ShowScreen();
  294.       }
  295.       break;
  296.     case Home:
  297.       Lc = 0;
  298.       ShowScreen();
  299.       break;
  300.     case EndKey:
  301.       if (Bot >= ScrSize) {
  302.         Lc = Bot;
  303.         ShowScreen();
  304.       }
  305.       break;
  306.     case Alt_S: FileSearch(); break;
  307.   }
  308. }
  309.  
  310.